unit core_2313;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, StdCtrls;

type

  { TForm2 }

  TForm2 = class(TForm)
    C10: TShape;
    C11: TShape;
    C12: TShape;
    C13: TShape;
    C14: TShape;
    C8: TShape;
    C9: TShape;
    DDR0: TShape;
    DDR1: TShape;
    DDR10: TShape;
    DDR11: TShape;
    DDR12: TShape;
    DDR13: TShape;
    DDR14: TShape;
    C0: TShape;
    C7: TShape;
    C1: TShape;
    C2: TShape;
    C3: TShape;
    DDR2: TShape;
    C4: TShape;
    C5: TShape;
    C6: TShape;
    DDR3: TShape;
    DDR4: TShape;
    DDR5: TShape;
    DDR6: TShape;
    DDR7: TShape;
    DDR8: TShape;
    DDR9: TShape;
    cnt0: TEdit;
    Image1: TImage;
    procedure C7MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 

procedure HAL; // исполнение такта переферией ядра

const
  TTL_HIGH   : double  = 3.7;
  TTL_LOW    : double  = 1.5;

  MAX_PORT   : integer = 2;

  SCAL_CNT0  : integer = $31;
  TCNT0      : integer = $52;
  TCCR0      : integer = $53;
  PORTB      : integer = $38;
  DDRB       : integer = $37;
  PINB       : integer = $36;
  PORTD      : integer = $32;
  DDRD       : integer = $31;
  PIND       : integer = $30;
type
  TPinout = class
    polygons    : array [0..3,0..2] of TPoint;
    clHi, clLo  : TColor;
    dir         : integer;

    constructor Create(owner : TShape);
    procedure Paint(Canvas : TCanvas);
  end;

  TConnection = class
    polygons          : array [0..1,0..2] of TPoint;
    clHi, clLo, clZ   : TColor;
    p0,p1,p2          : integer;

    constructor Create(owner : TShape);
    procedure Paint(Canvas : TCanvas);
    function  bool : boolean;
  end;

  TPort = record
    DDR_ADDR  : integer;
    PORT_ADDR : integer;
    PIN_ADDR  : integer;
    pins      : array [0..7] of TPinout;
    wire      : array [0..7] of TConnection;
  end;

var
  Form2 : TForm2;
  MCU_ASPACE : ^Byte;
  PORTS      : array [0..1] of TPort;
  TEST       : array [0..14] of TConnection;
  isPaint    : boolean = false;
  PRESCALER  : integer;

implementation

{ TPinout}

constructor TConnection.Create(owner : TShape);
begin
  p0 := 0;
  p1 := 0;
  p2 := 0;
  clHi := clRed;
  clLo := clBlue;
  clZ  := clGray;
  with owner do begin
// connection point debet
   polygons[0,0] := Point(left,top);
   polygons[0,1] := Point(left+width,top+height);
   polygons[0,2] := Point(left,top+height);
// connection point kredit
   polygons[1,0] := Point(left+width,top+height);
   polygons[1,1] := Point(left+width,top);
   polygons[1,2] := Point(left,top);
  end;
end;

procedure TConnection.Paint(Canvas : TCanvas);
var
 val : integer;
begin
 val := (p0+p1+p2) div 3;
 if val = 1 then
  Canvas.Brush.Color := clHi
 else if val = -1 then
  Canvas.Brush.Color := clLo
 else
  Canvas.Brush.Color := clZ;

 Canvas.Polygon(polygons[0]);
end;

function TConnection.bool : boolean;
begin
 if ((p0+p1+p2) div 3) > 0 then bool := true else bool := false;
end;

constructor TPinout.Create(owner : TShape);
begin
  clLo := clBlue;
  clHi := clRed;
  with owner do begin
// pin input DDR,OUT = 0,0
   polygons[0,0] := Point(left+width,top);
   polygons[0,1] := Point(left,top+height div 2);
   polygons[0,2] := Point(left+width,top+height);
// pin input pullup VCC DDR,OUT = 0,1
   polygons[1,0] := Point(left+width,top);
   polygons[1,1] := Point(left,top);
   polygons[1,2] := Point(left+width,top+height);
// pin output Low DDR, OUT = 10
   polygons[2,0] := Point(left,top);
   polygons[2,1] := Point(left+width,top+height div 2);
   polygons[2,2] := Point(left,top+height);
// pin output Hi DDR, OUT = 11
   polygons[3,0] := Point(left,top);
   polygons[3,1] := Point(left+width,top+height div 2);
   polygons[3,2] := Point(left,top+height);
  end;
end;

procedure TPinout.Paint(Canvas : TCanvas);
begin
 if dir <= 2 then
  Canvas.Brush.Color := clLo
 else
  Canvas.Brush.Color := clHi;

 Canvas.Polygon(polygons[dir]);
end;

const MASKSCAL : array [0..5] of dword = (0,$FFFFFFFF,8,64,256,1024);
const TCCR0_CS_MASK : integer = $00000007;

procedure HAL;
var
 i, j, bit, DIRECT, OUTPUT, INPUT, MASK, CS : integer;
begin
// Счетчик 0
 PRESCALER := PRESCALER + 1;
{ CS := integer(MCU_ASPACE[TCCR0]) AND TCCR0_CS_MASK;
// CS=1 : clk, CS=2 8: clk/0000.0000.1000, CS=3 64: clk/0000.0100.0000
// CS=4 : 256 clk/0001.0000.0000, CS=5 1024: clk/0100.0000.0000
 MASK := MASKSCAL[CS];
 if (PRESCALER OR MASK) = MASK  then begin
   MCU_ASPACE[TCNT0] := MCU_ASPACE[TCNT0] - 1;
   Form2.cnt0.Text:=format('%2.2X', [MCU_ASPACE[TCNT0]]);
 end;}
 for j:=0 to MAX_PORT-1 do with PORTS[j] do begin
  DIRECT := MCU_ASPACE[DDR_ADDR] shl 1;
  OUTPUT := MCU_ASPACE[PORT_ADDR];
  INPUT  := 0;
  for i:=0 to 7 do begin
   bit := (DIRECT and 2) OR (OUTPUT and 1);
   if pins[i]<>nil then begin
    pins[i].dir := bit;
    case bit of
     0: wire[i].p0 := 0;
     1: wire[i].p0 := 1;
     2: wire[i].p0 := -1;
     else wire[i].p0 := 1;
    end;
    if wire[i].bool then INPUT := INPUT OR $80;
   end;
   INPUT  := INPUT  shr 1;
   DIRECT := DIRECT shr 1;
   OUTPUT := OUTPUT shr 1;
  end;
  MCU_ASPACE[PIN_ADDR] := INPUT;
 end;
end;

{ TForm2 }

procedure TForm2.FormCreate(Sender: TObject);
var
 i, j : integer;
begin
  TEST[0]:=TConnection.Create(C0);
  TEST[1]:=TConnection.Create(C1);
  TEST[2]:=TConnection.Create(C2);
  TEST[3]:=TConnection.Create(C3);
  TEST[4]:=TConnection.Create(C4);
  TEST[5]:=TConnection.Create(C5);
  TEST[6]:=TConnection.Create(C6);
  TEST[7]:=TConnection.Create(C7);
  TEST[8]:=TConnection.Create(C8);
  TEST[9]:=TConnection.Create(C9);
  TEST[10]:=TConnection.Create(C10);
  TEST[11]:=TConnection.Create(C11);
  TEST[12]:=TConnection.Create(C12);
  TEST[13]:=TConnection.Create(C13);
  TEST[14]:=TConnection.Create(C14);
  with PORTS[0] do begin
    DDR_ADDR := DDRB;
    PORT_ADDR:= PORTB;
    PIN_ADDR := PINB;
    wire[0]:=TEST[0];
    wire[1]:=TEST[1];
    wire[2]:=TEST[2];
    wire[3]:=TEST[3];
    wire[4]:=TEST[4];
    wire[5]:=TEST[5];
    wire[6]:=TEST[6];
    wire[7]:=TEST[7];
    pins[0]:=TPinout.Create(DDR0);
    pins[1]:=TPinout.Create(DDR1);
    pins[2]:=TPinout.Create(DDR2);
    pins[3]:=TPinout.Create(DDR3);
    pins[4]:=TPinout.Create(DDR4);
    pins[5]:=TPinout.Create(DDR5);
    pins[6]:=TPinout.Create(DDR6);
    pins[7]:=TPinout.Create(DDR7);
  end;
  with PORTS[1] do begin
    DDR_ADDR := DDRD;
    PORT_ADDR := PORTD;
    PIN_ADDR  := PIND;
    wire[0]:=TEST[8];
    wire[1]:=TEST[9];
    wire[2]:=TEST[10];
    wire[3]:=TEST[11];
    wire[4]:=TEST[12];
    wire[5]:=TEST[13];
    wire[6]:=TEST[14];
    pins[0]:=TPinout.Create(DDR8);
    pins[1]:=TPinout.Create(DDR9);
    pins[2]:=TPinout.Create(DDR10);
    pins[3]:=TPinout.Create(DDR11);
    pins[4]:=TPinout.Create(DDR12);
    pins[5]:=TPinout.Create(DDR13);
    pins[6]:=TPinout.Create(DDR14);
    pins[7] := nil;
  end;
end;

procedure TForm2.C7MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
 i : integer;
begin
i := TShape(Sender).Tag;
case TEST[i].p1 of
  0: TEST[i].p1 := 1;
  1: TEST[i].p1 := -1;
  else TEST[i].p1 := 0;
end;
Form2.Refresh;
end;

procedure TForm2.FormClick(Sender: TObject);
begin

end;

procedure TForm2.FormPaint(Sender: TObject);
var
 j, i : integer;
begin
for i:=0 to 14 do begin
   TEST[i].Paint(Canvas);
end;
for j:=0 to MAX_PORT-1 do with PORTS[j] do begin
  for i:=0 to 7 do begin
   if PORTS[j].pins[i] <> nil then begin
    PORTS[j].pins[i].Paint(Canvas);
   end;
  end;
end;
end;


initialization
  {$I core_2313.lrs}

end.

